home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / quakecc.zip / FIGHT.QC < prev    next >
Text File  |  1996-07-25  |  8KB  |  410 lines

  1.  
  2. /*
  3.  
  4. A monster is in fight mode if it thinks it can effectively attack its
  5. enemy.
  6.  
  7. When it decides it can't attack, it goes into hunt mode.
  8.  
  9. */
  10.  
  11. float(float v) anglemod;
  12.  
  13. void() knight_atk1;
  14. void() knight_runatk1;
  15. void() ogre_smash1;
  16. void() ogre_swing1;
  17.  
  18. void() sham_smash1;
  19. void() sham_swingr1;
  20. void() sham_swingl1;
  21.  
  22. float()    DemonCheckAttack;
  23. void(float side)    Demon_Melee;
  24.  
  25. void(vector dest) ChooseTurn;
  26.  
  27. void() ai_face;
  28.  
  29.  
  30. float    enemy_vis, enemy_infront, enemy_range;
  31. float    enemy_yaw;
  32.  
  33.  
  34. void() knight_attack =
  35. {
  36.     local float        len;
  37.     
  38. // decide if now is a good swing time
  39.     len = vlen(self.enemy.origin+self.enemy.view_ofs - (self.origin+self.view_ofs));
  40.     
  41.     if (len<80)
  42.         knight_atk1 ();
  43.     else
  44.         knight_runatk1 ();
  45. };
  46.  
  47. //=============================================================================
  48.  
  49. /*
  50. ===========
  51. CheckAttack
  52.  
  53. The player is in view, so decide to move or launch an attack
  54. Returns FALSE if movement should continue
  55. ============
  56. */
  57. float() CheckAttack =
  58. {
  59.     local vector    spot1, spot2;    
  60.     local entity    targ;
  61.     local float        chance;
  62.  
  63.     targ = self.enemy;
  64.     
  65. // see if any entities are in the way of the shot
  66.     spot1 = self.origin + self.view_ofs;
  67.     spot2 = targ.origin + targ.view_ofs;
  68.  
  69.     traceline (spot1, spot2, FALSE, self);
  70.  
  71.     if (trace_ent != targ)
  72.         return FALSE;        // don't have a clear shot
  73.             
  74.     if (trace_inopen && trace_inwater)
  75.         return FALSE;            // sight line crossed contents
  76.  
  77.     if (enemy_range == RANGE_MELEE)
  78.     {    // melee attack
  79.         if (self.th_melee)
  80.         {
  81.             if (self.classname == "monster_knight")
  82.                 knight_attack ();
  83.             else
  84.                 self.th_melee ();
  85.             return TRUE;
  86.         }
  87.     }
  88.     
  89. // missile attack
  90.     if (!self.th_missile)
  91.         return FALSE;
  92.         
  93.     if (time < self.attack_finished)
  94.         return FALSE;
  95.         
  96.     if (enemy_range == RANGE_FAR)
  97.         return FALSE;
  98.         
  99.     if (enemy_range == RANGE_MELEE)
  100.     {
  101.         chance = 0.9;
  102.         self.attack_finished = 0;
  103.     }
  104.     else if (enemy_range == RANGE_NEAR)
  105.     {
  106.         if (self.th_melee)
  107.             chance = 0.2;
  108.         else
  109.             chance = 0.4;
  110.     }
  111.     else if (enemy_range == RANGE_MID)
  112.     {
  113.         if (self.th_melee)
  114.             chance = 0.05;
  115.         else
  116.             chance = 0.1;
  117.     }
  118.     else
  119.         chance = 0;
  120.  
  121.     if (random () < chance)
  122.     {
  123.         self.th_missile ();
  124.         SUB_AttackFinished (2*random());
  125.         return TRUE;
  126.     }
  127.  
  128.     return FALSE;
  129. };
  130.  
  131.  
  132. /*
  133. =============
  134. ai_face
  135.  
  136. Stay facing the enemy
  137. =============
  138. */
  139. void() ai_face =
  140. {
  141.     self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
  142.     ChangeYaw ();
  143. };
  144.  
  145. /*
  146. =============
  147. ai_charge
  148.  
  149. The monster is in a melee attack, so get as close as possible to .enemy
  150. =============
  151. */
  152. float (entity targ) visible;
  153. float(entity targ) infront;
  154. float(entity targ) range;
  155.  
  156. void(float d) ai_charge =
  157. {
  158.     ai_face ();    
  159.     movetogoal (d);        // done in C code...
  160. };
  161.  
  162. void() ai_charge_side =
  163. {
  164.     local    vector    dtemp;
  165.     local    float    heading;
  166.     
  167. // aim to the left of the enemy for a flyby
  168.  
  169.     self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
  170.     ChangeYaw ();
  171.  
  172.     makevectors (self.angles);
  173.     dtemp = self.enemy.origin - 30*v_right;
  174.     heading = vectoyaw(dtemp - self.origin);
  175.     
  176.     walkmove(heading, 20);
  177. };
  178.  
  179.  
  180. /*
  181. =============
  182. ai_melee
  183.  
  184. =============
  185. */
  186. void() ai_melee =
  187. {
  188.     local vector    delta;
  189.     local float     ldmg;
  190.  
  191.     if (!self.enemy)
  192.         return;        // removed before stroke
  193.         
  194.     delta = self.enemy.origin - self.origin;
  195.  
  196.     if (vlen(delta) > 60)
  197.         return;
  198.         
  199.     ldmg = (random() + random() + random()) * 3;
  200.     T_Damage (self.enemy, self, self, ldmg);
  201. };
  202.  
  203.  
  204. void() ai_melee_side =
  205. {
  206.     local vector    delta;
  207.     local float     ldmg;
  208.  
  209.     if (!self.enemy)
  210.         return;        // removed before stroke
  211.         
  212.     ai_charge_side();
  213.     
  214.     delta = self.enemy.origin - self.origin;
  215.  
  216.     if (vlen(delta) > 60)
  217.         return;
  218.     if (!CanDamage (self.enemy, self))
  219.         return;
  220.     ldmg = (random() + random() + random()) * 3;
  221.     T_Damage (self.enemy, self, self, ldmg);
  222. };
  223.  
  224.  
  225. //=============================================================================
  226.  
  227. /*
  228. ===========
  229. SoldierCheckAttack
  230.  
  231. The player is in view, so decide to move or launch an attack
  232. Returns FALSE if movement should continue
  233. ============
  234. */
  235. float() SoldierCheckAttack =
  236. {
  237.     local vector    spot1, spot2;    
  238.     local entity    targ;
  239.     local float        chance;
  240.  
  241.     targ = self.enemy;
  242.     
  243. // see if any entities are in the way of the shot
  244.     spot1 = self.origin + self.view_ofs;
  245.     spot2 = targ.origin + targ.view_ofs;
  246.  
  247.     traceline (spot1, spot2, FALSE, self);
  248.  
  249.     if (trace_inopen && trace_inwater)
  250.         return FALSE;            // sight line crossed contents
  251.  
  252.     if (trace_ent != targ)
  253.         return FALSE;    // don't have a clear shot
  254.             
  255.     
  256. // missile attack
  257.     if (time < self.attack_finished)
  258.         return FALSE;
  259.         
  260.     if (enemy_range == RANGE_FAR)
  261.         return FALSE;
  262.         
  263.     if (enemy_range == RANGE_MELEE)
  264.         chance = 0.9;
  265.     else if (enemy_range == RANGE_NEAR)
  266.         chance = 0.4;
  267.     else if (enemy_range == RANGE_MID)
  268.         chance = 0.05;
  269.     else
  270.         chance = 0;
  271.  
  272.     if (random () < chance)
  273.     {
  274.         self.th_missile ();
  275.         SUB_AttackFinished (1 + random());
  276.         if (random() < 0.3)
  277.             self.lefty = !self.lefty;
  278.  
  279.         return TRUE;
  280.     }
  281.  
  282.     return FALSE;
  283. };
  284. //=============================================================================
  285.  
  286. /*
  287. ===========
  288. ShamCheckAttack
  289.  
  290. The player is in view, so decide to move or launch an attack
  291. Returns FALSE if movement should continue
  292. ============
  293. */
  294. float() ShamCheckAttack =
  295. {
  296.     local vector    spot1, spot2;    
  297.     local entity    targ;
  298.     local float        chance;
  299.     local float        enemy_yaw;
  300.  
  301.     if (enemy_range == RANGE_MELEE)
  302.     {
  303.         if (CanDamage (self.enemy, self))
  304.         {
  305.             self.attack_state = AS_MELEE;
  306.             return TRUE;
  307.         }
  308.     }
  309.  
  310.     if (time < self.attack_finished)
  311.         return FALSE;
  312.     
  313.     if (!enemy_vis)
  314.         return FALSE;
  315.         
  316.     targ = self.enemy;
  317.     
  318. // see if any entities are in the way of the shot
  319.     spot1 = self.origin + self.view_ofs;
  320.     spot2 = targ.origin + targ.view_ofs;
  321.  
  322.     if (vlen(spot1 - spot2) > 600)
  323.         return FALSE;
  324.  
  325.     traceline (spot1, spot2, FALSE, self);
  326.  
  327.     if (trace_inopen && trace_inwater)
  328.         return FALSE;            // sight line crossed contents
  329.  
  330.     if (trace_ent != targ)
  331.     {
  332.         return FALSE;    // don't have a clear shot
  333.     }
  334.             
  335. // missile attack
  336.     if (enemy_range == RANGE_FAR)
  337.         return FALSE;
  338.         
  339.     self.attack_state = AS_MISSILE;
  340.     SUB_AttackFinished (2 + 2*random());
  341.     return TRUE;
  342. };
  343.  
  344. //============================================================================
  345.  
  346. /*
  347. ===========
  348. OgreCheckAttack
  349.  
  350. The player is in view, so decide to move or launch an attack
  351. Returns FALSE if movement should continue
  352. ============
  353. */
  354. float() OgreCheckAttack =
  355. {
  356.     local vector    spot1, spot2;    
  357.     local entity    targ;
  358.     local float        chance;
  359.  
  360.     if (enemy_range == RANGE_MELEE)
  361.     {
  362.         if (CanDamage (self.enemy, self))
  363.         {
  364.             self.attack_state = AS_MELEE;
  365.             return TRUE;
  366.         }
  367.     }
  368.  
  369.     if (time < self.attack_finished)
  370.         return FALSE;
  371.     
  372.     if (!enemy_vis)
  373.         return FALSE;
  374.         
  375.     targ = self.enemy;
  376.     
  377. // see if any entities are in the way of the shot
  378.     spot1 = self.origin + self.view_ofs;
  379.     spot2 = targ.origin + targ.view_ofs;
  380.  
  381.     traceline (spot1, spot2, FALSE, self);
  382.  
  383.     if (trace_inopen && trace_inwater)
  384.         return FALSE;            // sight line crossed contents
  385.  
  386.     if (trace_ent != targ)
  387.     {
  388.         return FALSE;    // don't have a clear shot
  389.     }
  390.             
  391. // missile attack
  392.     if (time < self.attack_finished)
  393.         return FALSE;
  394.         
  395.     if (enemy_range == RANGE_FAR)
  396.         return FALSE;
  397.         
  398.     else if (enemy_range == RANGE_NEAR)
  399.         chance = 0.10;
  400.     else if (enemy_range == RANGE_MID)
  401.         chance = 0.05;
  402.     else
  403.         chance = 0;
  404.  
  405.     self.attack_state = AS_MISSILE;
  406.     SUB_AttackFinished (1 + 2*random());
  407.     return TRUE;
  408. };
  409.  
  410.